/**
 * 
 */
package com.boshanam.util.user;

import java.util.Locale;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.boshanam.application.settings.ApplicationSettings;
import com.boshanam.model.entities.persistant.jpa.user.User;
import com.boshanam.model.entities.persistant.jpa.user.UserSettings;
import com.boshanam.model.vos.domain.user.UserSettingsVO;
import com.boshanam.model.vos.domain.user.UserVO;
import com.boshanam.model.vos.domain.user.UserVOImmutable;
import com.google.appengine.api.datastore.KeyFactory;

/**
 * @author Sivakumar Y, UserUtils.java Dec 21, 2009 3:32:33 AM www.ibigbang.net
 *         shiva.forums@gmail.com
 */
public class UserUtils {

	private static Log log = LogFactory.getLog(UserUtils.class);

	/**
	 * @param u
	 *            Entity retrived from Datastore (DAO)
	 * @return UserVOImmutable
	 */
	public static UserVOImmutable createImmutableVoFromEntity(User u) {
		return new UserVOImmutable(u.getKeyAsStringId(), u.getFirstName(), u
				.getLastName(), u.getMiddleName(), u.getPhoneNumber(), u
				.getBirthDate(), u.getUsername(), u.getPassword(),
				u.getEmail(), UserUtils.createVOFromUserSettings(u
						.getUserSettings()), u.isEnabled(), u.isVerified(), u
						.isAccountNonExpired(), u.isCredentialsNonExpired(), u
						.isAccountNonLocked(), u.getAuthorities(), u.getSigninHistory(), u
						.getDescription());
	}

	/**
	 * @param userSettings
	 * @return
	 */
	private static UserSettingsVO createVOFromUserSettings(
			UserSettings userSettings) {
		if(userSettings == null) {
			return new UserSettingsVO(null, ApplicationSettings.DEFAULT_THEME, stringToLocale("en_US")); 
		}
		return new UserSettingsVO(
				KeyFactory.keyToString(userSettings.getKey()), userSettings
						.getTheme(), stringToLocale(userSettings.getLocale()));
	}

	/**
	 * @param userSettings
	 * @return
	 */
	private static UserSettings createUserSettingsFromVO(
			UserSettingsVO userSettings) {
		return new UserSettings((userSettings.getID() != null) ? KeyFactory
				.stringToKey(userSettings.getID()) : null, userSettings
				.getTheme(), localeToString(userSettings.getLocale()));
	}

	/**
	 * @param locale
	 * @return String format of the locale. it is compatible with
	 *         java.util.Locale.toString() method. i.e it works exactly similar
	 *         to {@link #java.util.Locale.toString()} method. Added just for
	 *         giving documentation to {@link #stringToLocale(String)}
	 */
	private static String localeToString(Locale locale) {
		String language = locale.getLanguage();
		String country = locale.getCountry();
		String variant = locale.getVariant();

		boolean l = language.length() != 0;
		boolean c = country.length() != 0;
		boolean v = variant.length() != 0;
		StringBuilder result = new StringBuilder(language);
		if (c || (l && v)) {
			result.append('_').append(country); // This may just append '_'
		}
		if (v && (l || c)) {
			result.append('_').append(variant);
		}
		return result.toString();
	}

	/**
	 * @param locale
	 * @return Locale of the given String representation or java.util.Locale.US
	 *         if the given String is null. or Invalid String representation of
	 *         Locale.
	 */
	private static Locale stringToLocale(String locale) {
		if (locale == null) {
			log.fatal("Locale Not Loded Properly from Datastore: " +
					"NULL Locale loaded from data store, Returning \"java.util.Locale.US\"...");
			return Locale.US;
		}
		String[] tokens = locale.split("_");
		switch (tokens.length) {
		case 1:
			return new Locale(tokens[0]);
		case 2:
			return new Locale(tokens[0], tokens[1]);
		case 3:
			return new Locale(tokens[0], tokens[1], tokens[2]);
		default:
			log.fatal("Locale Not Loded Properly from Datastore: " +
					"Multiproperty Locale loaded...inconsistant number of values." +
					" or \"\" EMPTY String representation of Locale. returning \"java.util.Locale.US\"");
			return Locale.US;
		}
	}

	/**
	 * 
	 * @param u
	 *            UserVOImmutable, an immutable User Object returned by DAO
	 * @return UserVO
	 */
	public static UserVO createVoFromImmutableVo(UserVOImmutable u) {
		return new UserVO(u.getID(), u.getFirstName(), u.getLastName(), u
				.getMiddleName(), u.getPhoneNumber(), u.getBirthDate(), u
				.getUsername(), u.getPassword(), u.getEmail(), u
				.getUserSettings(), u.isEnabled(), u.isVerified(), u
				.isAccountNonExpired(), u.isCredentialsNonExpired(), u
				.isAccountNonLocked(), u.getAuthorities(), u.getSigninHistory(), u.getDescription());
	}

	/**
	 * Creates persistant User Entity from UserVO(Value Object).
	 * 
	 * @param u
	 * @return
	 */
	public static User createEntityFromVO(UserVO u) {
		return new User(((u.getID() == null || u.getID().equals("")) ? null
				: KeyFactory.stringToKey(u.getID())), u.getFirstName(), u
				.getLastName(), u.getMiddleName(), u.getPhoneNumber(), u
				.getBirthDate(), u.getUsername(), u.getPassword(),
				u.getEmail(), UserUtils.createUserSettingsFromVO(u
						.getUserSettings()), u.isEnabled(), u.isVerified(), u
						.isAccountNonExpired(), u.isCredentialsNonExpired(), u
						.isAccountNonLocked(), u.getAuthorities(), u.getSigninHistory(), u
						.getDescription());
	}

	/**
	 * @param merge
	 * @return
	 */
	public static UserVO createVoFromEntity(User u) {
		return new UserVO(u.getKeyAsStringId(), u.getFirstName(), u
				.getLastName(), u.getMiddleName(), u.getPhoneNumber(), u
				.getBirthDate(), u.getUsername(), u.getPassword(),
				u.getEmail(), UserUtils.createVOFromUserSettings(u
						.getUserSettings()), u.isEnabled(), u.isVerified(), u
						.isAccountNonExpired(), u.isCredentialsNonExpired(), u
						.isAccountNonLocked(), u.getAuthorities(), u.getSigninHistory(), u
						.getDescription());
	}

}
